﻿#ifndef __ZUISTRING_H__
#define __ZUISTRING_H__

#include "ZCommon.h"
namespace ZuiLib
{
	typedef char ZChar;

    struct ZCharRange
    {
        int minPos;
        int maxPos;
    };

	class ZString
	{
	public:
		enum { MAX_LOCAL_STRING_LEN = 31 };

		ZString();
		ZString(const ZChar ch);
		ZString(const ZString& src);
		ZString(const ZChar* str, int nLen = -1);
		ZString(const ZWChar* str, int nLen = -1);
		~ZString();

		void Empty();
		int GetLength() const;
		bool IsEmpty() const;
		ZChar GetAt(int nIndex) const;
		void Append(const ZChar* pstr, int nLength = -1);
		void Append(ZChar ch);
		void Assign(const ZChar* pstr, int nLength = -1);
		void Resize(int length);
		const ZChar* GetString() const;
		ZChar* GetData();

		void SetAt(int nIndex, ZChar ch);
		operator const ZChar*() const;

		ZChar operator[] (int nIndex) const;
		const ZString& operator=(const ZString& src);
		const ZString& operator=(const ZChar ch);
		const ZString& operator=(const ZChar* pstr);


		ZString operator+(const ZString& src) const;
		ZString operator+(const ZChar* pstr) const;
		const ZString& operator+=(const ZString& src);
		const ZString& operator+=(const ZChar* pstr);
		const ZString& operator+=(const ZChar ch);

		bool operator == (const ZChar* str) const;
		bool operator != (const ZChar* str) const;
		bool operator <= (const ZChar* str) const;
		bool operator <  (const ZChar* str) const;
		bool operator >= (const ZChar* str) const;
		bool operator >  (const ZChar* str) const;

		int Compare(const ZChar* pstr) const;
		int CompareNoCase(const ZChar* pstr) const;

		void MakeUpper();
		void MakeLower();

		ZString Left(int nLength) const;
		ZString Mid(int iPos, int nLength = -1) const;
		ZString Right(int nLength) const;

		int Find(ZChar ch, int iPos = 0) const;
		int Find(const ZChar* pstr, int iPos = 0) const;
		int ReverseFind(ZChar ch) const;
		int ReverseFind(const ZChar* str) const;

		int Replace(const ZChar* pstrFrom, const ZChar* pstrTo);
		int Replace(ZChar chFrom,ZChar chTo);

		bool Insert(int pos,const ZChar* text,int len=-1);
		bool Insert(int pos,ZChar text);

		bool Remove(int pos,int len=1);
		int Format(const ZChar* pstrFormat, ...);
		int Format(const ZChar* pstrFormat, va_list Args);
		int SmallFormat(const ZChar* pstrFormat, ...);

		uint32_t Hash();

	protected:
		int GetAssignSize(int size);

		ZChar* m_pstr;
		ZChar* m_pstrEnd;
		ZChar m_szBuffer[MAX_LOCAL_STRING_LEN + 1];
		int m_allocSize;//最大可容纳字符数
	};

	//引用计数字符串
	class ZRefString :public ZString ,public ZRefCountedBase
	{
	public:
		ZRefString() {
		}
		ZRefString(const ZChar ch) 
			:ZString(ch)
		{
		}
		ZRefString(const ZString& src)
			:ZString(src)
		{
		}
		ZRefString(const ZChar* str, int nLen = -1) 
			:ZString(str,nLen)
		{
		}
		ZRefString(const ZWChar* str, int nLen = -1) 
			:ZString(str,nLen)
		{
		}
		ZIMPLEMENT_REFCOUNTING(ZRefString);
	};

	typedef ZRefCountedPtr<ZRefString> ZRefStringPtr;

	class ZWString
	{
	public:
		enum { MAX_LOCAL_STRING_LEN = 63 };

		ZWString();
		ZWString(const ZWChar ch);
		ZWString(const ZWString& src);
		ZWString(const ZWChar* str, int nLen = -1);
		ZWString(const char* str, int nLen = -1);

		~ZWString();

		void Empty();
		int GetLength() const;
		bool IsEmpty() const;
		ZWChar GetAt(int nIndex) const;
		void Append(const ZWChar* pstr, int nLength = -1);
		void Append(ZWChar ch);
		void Assign(const ZWChar* pstr, int nLength = -1);
		
		void Resize(int length);//包含了结束符

		const ZWChar* GetString() const;
		ZWChar* GetData();

		void SetAt(int nIndex, ZWChar ch);
		operator const ZWChar*() const;

		ZWChar operator[] (int nIndex) const;
		const ZWString& operator=(const ZWString& src);
		const ZWString& operator=(const ZWChar ch);
		const ZWString& operator=(const ZWChar* pstr);


		ZWString operator+(const ZWString& src) const;
		ZWString operator+(const ZWChar* pstr) const;
		const ZWString& operator+=(const ZWString& src);
		const ZWString& operator+=(const ZWChar* pstr);
		const ZWString& operator+=(const ZWChar ch);

		bool operator == (const ZWChar* str) const;
		bool operator != (const ZWChar* str) const;
		bool operator <= (const ZWChar* str) const;
		bool operator <  (const ZWChar* str) const;
		bool operator >= (const ZWChar* str) const;
		bool operator >  (const ZWChar* str) const;

		int Compare(const ZWChar* pstr) const;
		int CompareNoCase(const ZWChar* pstr) const;

		void MakeUpper();
		void MakeLower();

		ZWString Left(int nLength) const;
		ZWString Mid(int iPos, int nLength = -1) const;
		ZWString Right(int nLength) const;

		int Find(ZWChar ch, int iPos = 0) const;
		int Find(const ZWChar* pstr, int iPos = 0) const;
		int ReverseFind(ZWChar ch) const;
		int ReverseFind(const ZWChar* pstr) const;
		int Replace(const ZWChar* pstrFrom, const ZWChar* pstrTo);

		bool Insert(int pos,const ZWChar* text,int len=-1);
		bool Insert(int pos,ZWChar text);
		bool Remove(int pos,int len=1);

		static inline const ZWChar* EmptyStr() {
				return &s_emptyChar;
		}

		uint32_t Hash();

#ifdef WIN32
		//调试输出使用
		std::wstring ToStdString();
#endif

	protected:
		int GetAssignSize(int size);
		ZWChar* m_pstr;
		ZWChar* m_pstrEnd;
		ZWChar m_szBuffer[MAX_LOCAL_STRING_LEN + 1];
		int m_allocSize;//最大可容纳字符数

		static const ZWChar s_emptyChar;
	};


	class ZRefWString :public ZWString, public ZRefCountedBase
	{
	public:
		ZRefWString() {
		}
		ZRefWString(const ZWChar ch)
			:ZWString(ch)
		{
		}
		ZRefWString(const ZWString& src)
			:ZWString(src)
		{
		}
		ZRefWString(const ZWChar* str, int nLen = -1)
			:ZWString(str, nLen)
		{
		}
		ZRefWString(const ZChar* str, int nLen = -1)
			:ZWString(str, nLen)
		{
		}
		ZIMPLEMENT_REFCOUNTING(ZRefWString);
	};
	typedef ZRefCountedPtr<ZRefWString> ZRefWStringPtr;

	//字符转换
	void Utf8ToUtf16(const ZString* utf8,ZWString* utf16);
	void Utf16ToUtf8(const ZWString* utf16,ZString* utf8);
}//namespace

#ifndef WIN32
#define stricmp strcasecmp
#define wcsicmp wcscasecmp
#endif


#endif //__ZUISTRING_H__
